package org.jvm.instruction.references.invokemethod;

import org.jvm.instruction.base.NoOperandsInstruction;
import org.jvm.nativemethod.NativeMethodRegister;
import org.jvm.rtda.heap.classmember.Method;
import org.jvm.rtda.thread.Frame;

import java.lang.reflect.InvocationTargetException;

/**
 * 执行本地方法
 * 本指令不依赖其他指令操作栈帧，而是使用JVM方法操作栈帧
 *
 * @author 海燕
 * @date 2023/2/19
 */
public class INVOKE_NATIVE extends NoOperandsInstruction {
    @Override
    public void execute(Frame frame) {
        Method method = frame.getMethod();
        String className = method.getKlass().getName();
        String methodName = method.getName();
        String methodDescriptor = method.getDescriptor();
        java.lang.reflect.Method nativeMethod = NativeMethodRegister.findNativeMethod(className, methodName, methodDescriptor);
        if (nativeMethod == null) {
            throw new RuntimeException("cannot find native method");
        }
        //调用JVM的本地方法，操作栈帧
        try {
            nativeMethod.invoke(null, frame);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
